/**
 * @file:          Filter_MovingAverage.c
 * @brief:
 * @details:
 * @author:        wjh
 * @date created:  2023.08.06
 * @version:       1.0.0
 * @par copyright (c):
 *
 * @par history (desc):
 *   version:1.0.0, wjh, 2023.08.06,11:48:06
 */

/* Include Files **************************************************************/
#include "Filter_MovingAverage.h"

/* Global Variable Define *****************************************************/

/* Function Define ************************************************************/

void Filter_MovingAverage_Init(struct Filter_MovingAverage *self)
{
    self->Run = Filter_MovingAverage_Run;
    self->InitBuff = Filter_MovingAverage_InitBuff;
    self->UpdateParam = Filter_MovingAverage_UpdateParam;

    self->UpdateParam(self);
}

float Filter_MovingAverage_Run(struct Filter_MovingAverage *self, float in)
{
    float out = 0;
    uint16 i = 0;

    if (self->param_en != 0)
    {
        self->in_x = in;
        self->x_buff[self->index] = self->in_x;
        self->index = (self->index + 1) % self->param_N;
        self->x_sum = 0;
        for (i = 0; i < self->param_N; i++)
        {
            self->x_sum += self->x_buff[i];
        }
        self->out_y = self->x_sum / self->param_N;
        out = self->out_y;
    }
    else
    {
        self->in_x = in;
        self->out_y = self->in_x;
        out = self->out_y;
    }

    return out;
}

float Filter_MovingAverage_InitBuff(struct Filter_MovingAverage *self, float init_value)
{
    for (uint16_t i = 0; i < self->param_N; i++)
    {
        self->x_buff[i] = init_value;
    }
}

void Filter_MovingAverage_UpdateParam(struct Filter_MovingAverage *self)
{
    if ((self->param_N == 0) && (self->param_fc > 0))
    {
        self->param_N = (uint32_t)(0.443 / self->param_Ts / self->param_fc);
        self->param_N = self->param_N > MOVING_AVERAGE_MAX_WINDOW_SIZE ? MOVING_AVERAGE_MAX_WINDOW_SIZE : self->param_N;
        self->param_fc = 0.443 / self->param_Ts / self->param_N;
    }
    else if ((self->param_N > 0) && (self->param_fc == 0))
    {
        self->param_N = self->param_N > MOVING_AVERAGE_MAX_WINDOW_SIZE ? MOVING_AVERAGE_MAX_WINDOW_SIZE : self->param_N;
        self->param_fc = 0.443 / self->param_Ts / self->param_N;
    }
    else if ((self->param_N > 0) && (self->param_fc > 0))
    {
        self->param_N = self->param_N > MOVING_AVERAGE_MAX_WINDOW_SIZE ? MOVING_AVERAGE_MAX_WINDOW_SIZE : self->param_N;
        self->param_fc = 0.443 / self->param_Ts / self->param_N;
    }
    else
    {
        self->param_en = 0;
    }
}